package GameEngine;

import processing.core.PApplet;
import processing.core.PImage;
import GameEngine.Animation.Programmed.BeamAnimation;
import GameEngine.Animation.Programmed.LoopAnimation;
import GameEngine.Animation.Programmed.StepAnimation;
import GameEngine.Animation.Programmed.WaveAnimation;
import GameEngine.Animation.Translation.ImageTranslation;
import GameEngine.Animation.Translation.KeyFrame;
import GameEngine.Drawables.AnimatedSprite;
import GameEngine.Drawables.GameObjects.Band;
import GameEngine.Drawables.GameObjects.Mountain;
import GameEngine.Gui.GraphicsButton;
import GameEngine.Gui.Menu;
import GameEngine.Gui.Event.DefaultKeyEventListener;
import GameEngine.Gui.Event.KeyEvent;
import GameEngine.Gui.Event.KeyEventProcessor;
import GameEngine.Gui.Event.TouchEvent;
import GameEngine.Gui.Event.TouchEventProcessor;
import GameEngine.Level.XML.TileStudioTileLayer;
import GameEngine.helper.PAppletBridge;

public class SpriteMap extends PApplet {

	int count = 0;
	int c = 10;

	// The runners
	AnimatedSprite[] Runners = new AnimatedSprite[1];

	// Level
	// BlockLevel LV = new BlockLevel();
	private Band BND;
	private int direction = -1;

	// Animationen
	BeamAnimation BA;
	WaveAnimation WA;

	// ImageTranslation
	ImageTranslation TL;
	int frameNumber = 0;

	// Menue
	Menu MN;
	TouchEventProcessor EP = new TouchEventProcessor();
	KeyEventProcessor KEP = new KeyEventProcessor();

	Mountain mnt;
	StepAnimation SA;

	// XML Loading
	private TileStudioTileLayer tsl;

	public void setup() {
		initAnimations();
		testKeyFraming();
		testXMLLoading();

		size(500, 340);
		frameRate(80);

	}

	private void testXMLLoading() {
		tsl = new TileStudioTileLayer("welt.xml", 32, 300);
	}

	private void testKeyFraming() {
		TL = new ImageTranslation(750, "menu.png");
		TL = new ImageTranslation(750, MN.toImage());
		KeyFrame kf = new KeyFrame(0, 300, 200, 0, CENTER, 255, 0.4f, 0.4f);
		TL.add(kf);
		KeyFrame kf1 = new KeyFrame(100, 300, 200, 0, CENTER, 255, 0.4f, 0.4f);
		TL.add(kf1);

		float scale = 0.4f;
		float rot = 0;
		for (int i = 0; i < 50; i++) {
			KeyFrame kfn = new KeyFrame(100 + i * 7, 300, 200, rot, CENTER,
					255, scale, scale);
			if (i % 2 == 0) {
				scale = 0.42f;
				rot = -5;
			} else {
				scale = 0.4f;
				rot = 5;
			}
			TL.add(kfn);
		}

		KeyFrame kf2 = new KeyFrame(600, 300, 200, 0, CENTER, 255, 0.4f, 0.4f);
		TL.add(kf2);

		TL.interpolate();
	}

	private void initAnimations() {
		// Bridge zu PApplet muss gesetzt werden
		PAppletBridge pab = new PAppletBridge(this);

		mnt = new Mountain();
		BND = new Band(100);

		LoopAnimation LA = new LoopAnimation(30, 0, 25);
		for (int i = 0; i < Runners.length; i++) {
			Runners[i] = new AnimatedSprite("SpriteSheetSanta-Neu.png", 25, LA);
		}

		/*
		 * PImage sheet = loadImage("running.png"); for (int i = 0; i <
		 * Runner.length; i++) { Runner[i] = new AnimatedSprite(sheet); }
		 */
		

		SA = new StepAnimation(1);

		BA = new BeamAnimation(80, 360, 200);
		// BeamAnimation BA = new BeamAnimation(80, 360, 200);
		WA = new WaveAnimation(40, 200);
		// EllipseAnimation EA = new EllipseAnimation (60, 200);
		// ArrowAnimation AA = new ArrowAnimation (30, 250);
		// BubbleAnimation BBLA = new BubbleAnimation (50, 100);

		setupMenu();

		setupKeyListener();

	}

	private void setupKeyListener() {
		// TODO Auto-generated method stub
		KEP.registerKeyEventListener(new DefaultKeyEventListener());
	}

	private void setupMenu() {
		PImage img = loadImage("gui/menu.png");
		MN = new Menu(img, 0, 0, img.width, img.height);

		PImage buttonImg = loadImage("gui/button-red.png");
		int spacing = 0;
		for (int i = 0; i < 3; i++) {
			if (i > 0) {
				spacing = 10;
			}
			GraphicsButton gb = new GraphicsButton(buttonImg, 20, 70 * i + 15
					+ spacing * i, buttonImg.width, buttonImg.height);

			EP.registerListener(gb);
			MN.add(gb);
		}
	}

	public void draw() {
		background(0xff33198B);

		mnt.drawBerge();

		int offset = (int) (SA.currentValue() * 2.5f);
		// BND.drawAt(-offset, 150);
		// BND.drawAt(-offset, 250);
		//BND.drawAt(-offset, 280);

		drawRunnersAt(0, 0);

		animate();

		TL.draw(frameNumber % 750);
		frameNumber++;

		// als Letztes das Overlay
		// overlay();

		// Auswerten der (GUI)-Events
		EP.sendEvents();

		// Auswerten der (Tastatur)-Events
		KEP.sendEvents();
		
	}

	private void overlay() {
		MN.drawAt(50, 50);
		MN.setActive(true);
	}

	private void drawRunnersAt(int pX, int pY) {

		pushMatrix();
		imageMode(CENTER);
		translate(mouseX, mouseY);
		// rotate(radians(count/0.6f));
		line(pX - 100, pY - 43, pX + 100, pY - 43);
		drawRunners(pX, pY);
		line(pX - 100, pY + 43, pX + 100, pY + 43);
		popMatrix();
	}

	private void drawRunners(int pX, int pY) {
		for (int i = 0; i < Runners.length; i++) {
			Runners[i].setFlipped(direction < 0);
			Runners[i].setPosX(pX + (i % 8) * 40);
			Runners[i].setPosY(pY + (i / 8) * 40);
			Runners[i].draw();
		}
	}

	private void animate() {
		// Animationen ausf\u00fchren
		BA.animate(mouseX, mouseY);
		WA.animate(mouseX + 100, mouseY);
	}

	public void mousePressed() {
		direction = -direction;
		mnt.setDirection(direction);
		print("frameRate = ");
		println(frameRate);

		// Animationen starten
		BA.start();
		WA.start();

		EP.add(new TouchEvent(mouseX, mouseY));
	}

	public void keyPressed() {
		KEP.add(new KeyEvent(key, keyCode));
		System.out.println(key + ":" + keyCode);
	}

	static public void main(String[] passedArgs) {
		String[] appletArgs = new String[] { "GameEngine.SpriteMap" };
		if (passedArgs != null) {
			PApplet.main(concat(appletArgs, passedArgs));
		} else {
			PApplet.main(appletArgs);
		}
	}

}
